package net.googlecode.harchenko.task3;

import java.math.BigDecimal;

/**
 * Created by IntelliJ IDEA.
 * User: dima
 * Date: 3/25/11
 * Time: 8:37 PM
 * To change this template use File | Settings | File Templates.
 */
public class SalaryCalculator {

    /**
     * Working hours per month.
     */
    private final static BigDecimal HOURS_IN_MONTH = new BigDecimal(170);
    /**
     * Tax for the employees.
     */
    private BigDecimal taxEmployee = new BigDecimal(125);
    /**
     * Tax for the managers.
     */
    private BigDecimal taxManager = new BigDecimal(250);
    /**
     * Tax for the directors.
     */
    private BigDecimal taxDirector = new BigDecimal(500);


    /**
     * Standart constructor.
     */
    public SalaryCalculator() {

    }

    /**
     * Constructor with parameters.
     *
     * @param taxEmployee Tax for Employee
     * @param taxManager  Tax for Manager
     * @param taxDirector Tax for Director
     */
    public SalaryCalculator(final BigDecimal taxEmployee,
                            final BigDecimal taxManager, final BigDecimal taxDirector) {

        this.taxDirector = taxDirector;
        this.taxEmployee = taxEmployee;
        this.taxManager = taxManager;
    }

    /**
     * Sets the tax of Employee.
     *
     * @param taxEmployee Tax of Employee.
     */
    public void setTaxEmployee(BigDecimal taxEmployee) {
        this.taxEmployee = taxEmployee;
    }

    /**
     * @return Tax for Employee.
     */
    public BigDecimal getTaxEmployee() {
        return taxEmployee;
    }

    /**
     * @return Tax of Manager
     */
    public BigDecimal getTaxManager() {
        return taxManager;
    }

    /**
     * Sets the tax of Manager.
     *
     * @param taxManager Tax of Manager.
     */
    public void setTaxManager(BigDecimal taxManager) {
        this.taxManager = taxManager;
    }

    /**
     * @return Tax of Director
     */
    public BigDecimal getTaxDirector() {
        return taxDirector;
    }

    /**
     * Sets the tax of Director.
     *
     * @param taxDirector Tax of Director.
     */
    public void setTaxDirector(BigDecimal taxDirector) {
        this.taxDirector = taxDirector;
    }

    /**
     * Calculate salary for Employee.
     *
     * @param prs Person, whoos salary is calculating.
     * @return Salary of the person.
     */
    public BigDecimal calcForEmployee(final Employee prs) {

        BigDecimal salary;
        if (prs.isPerHour()) {
            salary = HOURS_IN_MONTH.multiply(prs.getRate());
        } else {
            salary = prs.getRate().multiply(prs.getExperience());
        }
        salary = salary.add(prs.getBonusAmt());
        salary = salary.subtract(taxEmployee);
        return salary;
    }

    /**
     * Calculate salary for Manager.
     *
     * @param prs Person, whoos salary is calculating.
     * @return Salary of the person.
     */
    public BigDecimal calcForManager(final Manager prs) {

        BigDecimal salary;
        if (prs.isPerHour()) {
            salary = HOURS_IN_MONTH.multiply(prs.getRate());
        } else {
            salary = prs.getRate();
        }
        salary = salary.add(prs.getBonusAmt());
        salary = salary.subtract(taxManager);
        return salary;
    }

    /**
     * Calculate salary for Director.
     *
     * @param prs Person, whoos salary is calculating.
     * @return Salary of the person.
     */
    public BigDecimal calcForDirector(final Director prs) {

        BigDecimal salary;

        salary = HOURS_IN_MONTH.multiply(prs.getRate());
        salary = salary.add(prs.getBonusAmt());
        salary = salary.subtract(taxDirector);
        return salary;
    }

    /**
     * Calculate salary for Person.
     *
     * @param person Person, whoos salary is calculating.
     * @return Salary of the person.
     */
    public BigDecimal calcSalary(final Person person) throws Exception {
        if (person instanceof Employee) {
            return calcForEmployee((Employee) person);
        } else if (person instanceof Manager) {
            return calcForManager((Manager) person);
        } else if (person instanceof Director) {
            return calcForDirector((Director) person);
        } else {
            throw new Exception("Unknown instance of. ");
        }
    }
}
